/**
 * @file 属性、节点装饰器
 * @author DuskyHuang 圣子
*/

import { Component, Node } from "cc"
import { findComp, findNode } from "../cc";
import { swapper } from "./swapper";

/** 
 * @param name 节点名称
 * @param paths 节点路径
 * @description 当方法参数为空时返回属性同名子节点
 * @return 指定节点
*/
export const node:
    DecoratorSwapper<PropertyDecorator, [name?: string, ...paths: string[]]>
    =
    swapper<PropertyDecorator>(([target, property]: Parameters<PropertyDecorator>, name?: string, ...paths: string[]) => {
        const onLoad = Reflect.get(target, 'onLoad') as Handler;
        Reflect.set(target, 'onLoad', function (...params: any) {
            const node = findNode(name ?? property as string, this as Component, ...paths) as Node;
            node && Reflect.set(this, property, node);
            Function.invoke(onLoad, this, ...params);
        });
    });

/** 挂载组件方法 */
export const comp:
    <T extends Component>(Comp: ConcreteClass<T>, ...paths: string[]) => PropertyDecorator
    = <T extends Component>(Comp: ConcreteClass<T>, ...paths: string[]) => {
        return function ([target, property]: Parameters<PropertyDecorator>) {
            const onLoad = Reflect.get(target, 'onLoad') as Handler;
            Reflect.set(target, 'onLoad', function (...params: any) {
                const comp = findComp(Comp, this as Component, ...paths) as T;
                comp && Reflect.set(this, property, comp);
                Function.invoke(onLoad, this, ...params);
            });
        }
    };